﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Relocation.Com;
using Relocation.Data;
using System.ComponentModel;
using Relocation.Com.Tools;

namespace Relocation.Base.UI
{
	public class BaseControl : UserControl
	{

		private readonly log4net.ILog _Log;

		/// <summary>
		/// 日志对象
		/// </summary>
		public log4net.ILog Log
		{
			get
			{
				return this._Log;
			}
		}

		/// <summary>
		/// Session 对象
		/// </summary>
		protected Session Session
		{
			get;
			set;
		}

		public BaseControl()
		{
			_Log = log4net.LogManager.GetLogger(this.GetType());
			this.Load += new EventHandler(RelocationBase_Load);
		}

		public BaseControl(Session session):this()
		{
			this.Session = session;			
		}



		#region 统一验证、搜索、赋值、取值、权限


		/// <summary>
		/// 需要验证的Control集合
		/// </summary>
		private List<Control> ValidatorControls = new List<Control>();

		/// <summary>
		/// 需要搜索的Control集合
		/// </summary>
		private List<Control> SearchControls = new List<Control>();
		private ErrorProvider errorProvider;
		private IContainer components;

		/// <summary>
		/// 字段控件（用于重置）
		/// </summary>
		private List<Control> FieldControls = new List<Control>();

		private void RelocationBase_Load(object sender, EventArgs e)
		{
			InitControls(this.Controls);
		}

		/// <summary>
		/// 遍历窗体内的所有控件，初始化验证
		/// </summary>
		private void InitControls(Control.ControlCollection controls)
		{
			foreach (Control control in controls)
			{
				InitControl(control);
				if (control.Controls.Count > 0)
					InitControls(control.Controls);
			}
		}

		/// <summary>
		/// 根据每个Control的Tag属性初始化
		/// </summary>
		/// <param name="control"></param>
		private void InitControl(Control control)
		{
			ControlTag controlTag = control.Tag as ControlTag;
			if (controlTag == null)
				return;

			if (controlTag.ValidatorInfo != null)
			{
				ValidatorControls.Add(control);
				//绑定验证的相关事件
				InitControlValidator(control, controlTag.ValidatorInfo);
			}

			//设置搜索信息
			if (controlTag.SearchInfo != null)
			{
				SearchControls.Add(control);
			}

			if (!String.IsNullOrEmpty(controlTag.FieldName))
			{
				FieldControls.Add(control);
			}

			//设置权限信息
			if (controlTag.RoleInfo != null)
			{
				InitControlRole(control, controlTag.RoleInfo, this.Session == null ? null : this.Session.User);
			}
		}

		/// <summary>
		/// 根据权限禁用指定控件
		/// </summary>
		/// <param name="control"></param>
		private void InitControlRole(Control control, RoleInfo roleInfo, User user)
		{
			if (control == null || roleInfo == null)
				return;
			//如果没有用户信息或者用户的角色为空，则禁用控件
			if (user == null || String.IsNullOrEmpty(user.role))
			{
				control.Enabled = false;
				return;
			}

			//如果用户的角色不在允许访问的角色列表中，则禁用控件
			control.Enabled = roleInfo.ShowInRoles.Any(t => t.Equals(user.role));
		}


		/// <summary>
		/// 绑定控件的验证信息
		/// </summary>
		/// <param name="control"></param>
		/// <param name="validatorInfo"></param>
		private void InitControlValidator(Control control, ValidatorInfo validatorInfo)
		{
			if (control == null || validatorInfo == null)
				return;
			control.Validating += new System.ComponentModel.CancelEventHandler(ControlValidatorEvent);

		}

		private void ControlValidatorEvent(object sender, CancelEventArgs e)
		{
			ControlValidator(sender as Control, e);
		}

		private bool ControlValidator(Control contorl, CancelEventArgs e)
		{
			if (contorl == null)
				return true;

			ControlTag controlTag = contorl.Tag as ControlTag;
			if (controlTag == null)
				return true;
			ValidatorInfo validatorInfo = controlTag.ValidatorInfo;
			if (validatorInfo == null)
				return true;

			Relocation.Com.ValidatorInfo.ValidatorResult validatorResult = null;
			if (validatorInfo.Validator != null)
			{
				//使用自定义的方法进行验证
				validatorResult = validatorInfo.Validator(contorl);
			}
			else
			{
				String value = contorl.Text;

				if (!String.IsNullOrEmpty(validatorInfo.RuleString))
				{
					if (!Validator.rule(value, validatorInfo.RuleString))
					{
						validatorResult = new Relocation.Com.ValidatorInfo.ValidatorResult(false, validatorInfo.RuleErrorString);
					}
				}
				else if (validatorInfo.IsRequired && String.IsNullOrEmpty(value))
				{
					validatorResult = new Relocation.Com.ValidatorInfo.ValidatorResult(false, "必须填写");
				}
				else
				{
					switch (validatorInfo.ValidatorType)
					{
						case Relocation.Com.ValidatorInfo.ValidatorTypes.String:
							if (validatorInfo.MinLength != validatorInfo.MaxLength && validatorInfo.MaxLength != 0)
							{
								if (!Validator.length(value, validatorInfo.MinLength, validatorInfo.MinLength))
								{
									String errorStr = "长度应该在" + validatorInfo.MinLength.ToString() + "到" + validatorInfo.MaxLength.ToString() + "之间";
									validatorResult = new Relocation.Com.ValidatorInfo.ValidatorResult(false, errorStr);
								}
							}
							break;
						case Relocation.Com.ValidatorInfo.ValidatorTypes.Number:
							if (!Validator.Num(value))
							{
								validatorResult = new Relocation.Com.ValidatorInfo.ValidatorResult(false, "只能填写整数");
							}
							break;
						case Relocation.Com.ValidatorInfo.ValidatorTypes.Digit:
							if (!Validator.Digit(value))
							{
								validatorResult = new Relocation.Com.ValidatorInfo.ValidatorResult(false, "只能填写数字");
							}
							break;
						case Relocation.Com.ValidatorInfo.ValidatorTypes.DateTime:
							if (!Validator.Datetime(value))
							{
								validatorResult = new Relocation.Com.ValidatorInfo.ValidatorResult(false, "只能填写日期");
							}
							break;
						case Relocation.Com.ValidatorInfo.ValidatorTypes.Idcards:
							if (!Validator.CheckCid(value))
							{
								validatorResult = new Relocation.Com.ValidatorInfo.ValidatorResult(false, "请填写正确的身份证号");
							}
							break;
						case Relocation.Com.ValidatorInfo.ValidatorTypes.Idcard15:
							if (!Validator.Idcard15(value))
							{
								validatorResult = new Relocation.Com.ValidatorInfo.ValidatorResult(false, "请填写正确的身份证号");
							}
							break;
						case Relocation.Com.ValidatorInfo.ValidatorTypes.Idcard18:
							if (!Validator.Idcard18(value))
							{
								validatorResult = new Relocation.Com.ValidatorInfo.ValidatorResult(false, "请填写正确的身份证号");
							}
							break;

					}

				}

			}

			return ShowControlErr(contorl, validatorResult);
		}

		/// <summary>
		/// 显示错误信息
		/// </summary>
		/// <param name="contorl"></param>
		/// <param name="validatorResult"></param>
		private bool ShowControlErr(Control contorl, ValidatorInfo.ValidatorResult validatorResult)
		{
			if (validatorResult == null || validatorResult.Success)
			{
				this.errorProvider.SetError(contorl, "");
				return true;
			}
			else
			{
				this.errorProvider.SetError(contorl, validatorResult.ErrorMessage);
				return false;
			}

		}

		/// <summary>
		/// 验证所有需要验证的控件，并返回验证结构
		/// </summary>
		protected bool ValidatorAllControls()
		{
			if (ValidatorControls == null)
				return true;
			bool result = true;
			//遍历所有需要验证的控件
			foreach (Control control in ValidatorControls)
			{
				if (!ControlValidator(control, null))
				{
					result = false;
				}
			}
			return result;
		}

		/// <summary>
		/// 返回搜索字符串
		/// </summary>
		/// <returns></returns>
		protected string GetSearchString()
		{
			StringBuilder queryString = new StringBuilder();
			foreach (Control control in SearchControls)
			{
				ControlTag controlTag = control.Tag as ControlTag;
				if (controlTag == null)
					continue;
				if (controlTag.SearchInfo == null)
					continue;

				String value = control.Text.Trim();
				String fieldName = controlTag.SearchInfo.SearchField;
				switch (controlTag.SearchInfo.SearchFieldType)
				{
					case SearchInfo.SearchFieldTypes.String:
						queryString.Append(" and");
						queryString.Append(" it." + fieldName);
						queryString.Append(" like '%" + value.ToString().Replace("'", "''") + "%'");
						break;
					case SearchInfo.SearchFieldTypes.Number:
						queryString.Append(" and");
						queryString.Append(" it." + fieldName);
						queryString.Append("=");
						queryString.Append(value);
						break;
					case SearchInfo.SearchFieldTypes.DateTime:
						queryString.Append(" and");
						DateTime dateValue = Convert.ToDateTime(value);
						queryString.Append("and Year(it." + fieldName + ")=" + dateValue.Year + " and Month(it." + fieldName + ")=" + dateValue.Month + " and Day(it." + fieldName + ")=" + dateValue.Day);
						break;

				}
			}
			if (queryString.Length > 4)
				queryString.Remove(0, 4);
			return queryString.ToString();
		}

		/// <summary>
		/// 重置
		/// </summary>
		protected void Reset()
		{
			if (this.FieldControls == null)
				return;
			foreach (Control control in FieldControls)
			{
				control.Text = string.Empty;
			}
		}

		/// <summary>
		/// 通过反射以及对控件Tag属性的配置，自动赋值
		/// </summary>
		/// <param name="tagEntity"></param>
		protected void GetValue(Object entity)
		{
			foreach (Control control in FieldControls)
			{
				ControlTag controlTag = control.Tag as ControlTag;
				if (controlTag == null)
					continue;
				if (string.IsNullOrEmpty(controlTag.FieldName))
					continue;
				Reflector.SetPropertyValue(entity, controlTag.FieldName, control.Text);


			}
			return;
		}

		/// <summary>
		/// 通过反射以及对控件Tag属性的配置，自动填充文本框
		/// </summary>
		/// <param name="tagEntity"></param>
		protected void SetValue(Object entity)
		{
			foreach (Control control in FieldControls)
			{
				ControlTag controlTag = control.Tag as ControlTag;
				if (controlTag == null)
					continue;
				if (string.IsNullOrEmpty(controlTag.FieldName))
					continue;
				//PropertyInfo pInfo=Reflector.GetPropertyValue(tagEntity,controlTag.FieldName);
				control.Text = Reflector.GetPropertyValue(entity, controlTag.FieldName).ToString();
				//Reflector.SetPropertyValue(tagEntity, controlTag.FieldName, control.Text);


			}
			return;
		}
		#endregion

		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
			this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
			((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
			this.SuspendLayout();
			// 
			// errorProvider
			// 
			this.errorProvider.ContainerControl = this;
			// 
			// BaseControl
			// 
			this.Name = "BaseControl";
			((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
			this.ResumeLayout(false);

		}
	}
}
